home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / Looching2.0 / Bark.m < prev    next >
Encoding:
Text File  |  1991-09-07  |  9.6 KB  |  275 lines

  1. /* The following files must be imported. */
  2. #ifndef UNITGENERATORS_H
  3. #define UNITGENERATORS_H
  4.  
  5. #import <musickit/musickit.h>
  6. #import    <musickit/unitgenerators/Add2UGxxx.h> 
  7. #import <musickit/unitgenerators/Add2UGyyy.h> 
  8. #import <musickit/unitgenerators/AsympUGy.h> 
  9. #import <musickit/unitgenerators/DelayUGyxx.h> 
  10. #import <musickit/unitgenerators/Mul2UGyyy.h> 
  11. #import <musickit/unitgenerators/OscgUGyy.h> 
  12. #import <musickit/unitgenerators/OscgafiUGxyyy.h> 
  13. #import <musickit/unitgenerators/Out1aUGx.h> 
  14. #import <musickit/unitgenerators/Out1bUGy.h> 
  15.  
  16. #define MK_OSCFREQSCALE 256.0 /* Used by Oscg and Oscgaf */
  17. #endif UNITGENERATORS_H
  18.  
  19. #import "Bark.h"
  20.  
  21. @implementation Bark:SynthPatch
  22. {
  23.     id LoochWave;
  24. }
  25.  
  26. static int i = 0;
  27.  
  28. /* A static integer is created for each synthElement. */
  29. static int    osc[2],            /* wave UG */
  30.         ampEnvUG,    /* amplitude envelope UG */
  31.         ampPatchpoint,    /* amplitude patch point */
  32.         freqOscUG[2],    /* frequency vibrato UG */
  33.         vibDeviateUG[2],    /* base deviation of note */
  34.         vibMulUG[2],    /* vibrato increment calculator */
  35.         vibMulIn1[2],    /* vib oscil input patch point */
  36.         vibMulIn2[2],    /* vib base input patch point */
  37.         vibBaseUG[2],    /* base frequency of note */
  38.         freqEnvUG[2],    /* frequency of note adder */
  39.         freqEnvIn1[2],    /* freq adder input 1 */
  40.         freqEnvIn2[2],    /* freq adder input 2 */
  41.         freqPatchpoint[2],    /* frequency patch point */
  42.         oscOutPatchpoint[2],    /* output of the two oscil chains */
  43.         oscSum,        /* add the two oscil chains */
  44.         delayUG,    /* digital delay unit generator */
  45.         delayIn,    /* delay line input patch point */
  46.         delayOut,    /* delay line output patch point */
  47.         stereoOutA,    /* sound output UG for channel 0 */
  48.         stereoOutB,    /* sound output UG for channel 1 */
  49.         outPatchpointA,    /* SynthData */
  50.         outPatchpointB, /* SynthData -- whatever */
  51.         DelayLine;    /* SynthData memory for delay */
  52.  
  53. + patchTemplateFor:aNote
  54. /* The argument is ignored in this implementation. */
  55. {
  56.     int DelayLength,j;
  57.  
  58.     /* Step 1: Create an instance of the PatchTemplate class. */
  59.     static id theTemplate = nil;
  60. // I took this out to give me four different templates for 4 delay lines
  61. //    if (theTemplate)
  62. //      return theTemplate;
  63.     theTemplate = [PatchTemplate new];
  64.  
  65.     /* Step 2: Add synthElement specifications to the PatchTemplate.  */
  66.     ampEnvUG = [theTemplate addUnitGenerator:[AsympUGy class]];
  67.   for (j = 0; j < 2; j++) {
  68.     vibBaseUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]];
  69.     vibDeviateUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]];
  70.     freqOscUG[j] = [theTemplate addUnitGenerator:[OscgUGyy class]];
  71.     vibMulUG[j] = [theTemplate addUnitGenerator:[Mul2UGyyy class]];
  72.     freqEnvUG[j] = [theTemplate addUnitGenerator:[Add2UGyyy class]];
  73.     osc[j] = [theTemplate addUnitGenerator:[OscgafiUGxyyy class]];
  74.   }
  75.  
  76.     oscSum = [theTemplate addUnitGenerator:[Add2UGxxx class]];
  77.     delayUG = [theTemplate addUnitGenerator:[DelayUGyxx class]];
  78.     stereoOutA = [theTemplate addUnitGenerator:[Out1aUGx class]];
  79.     stereoOutB = [theTemplate addUnitGenerator:[Out1bUGy class]];
  80.     
  81.     switch(i) {
  82.     case 0:
  83.         DelayLength = 500;
  84.         break;
  85.     case 1:
  86.         DelayLength = 85;
  87.         break;
  88.     case 2:
  89.         DelayLength = 40;
  90.         break;
  91.     case 3:
  92.         DelayLength = 5;
  93.         break;
  94.     default:
  95.         fprintf(stderr,"DelayLength problems!\n");
  96.         DelayLength = 1;
  97.     }
  98.  
  99.     DelayLine = [theTemplate addSynthData:MK_xData length:DelayLength];
  100.     
  101.     ampPatchpoint = [theTemplate addPatchpoint:MK_yPatch];
  102.   for (j = 0; j < 2; j++) {
  103.     vibMulIn1[j] = [theTemplate addPatchpoint:MK_yPatch];
  104.     vibMulIn2[j] = [theTemplate addPatchpoint:MK_yPatch];
  105.     freqEnvIn1[j] = [theTemplate addPatchpoint:MK_yPatch];
  106.     freqEnvIn2[j] = [theTemplate addPatchpoint:MK_yPatch];
  107.     freqPatchpoint[j] = [theTemplate addPatchpoint:MK_yPatch];
  108.     oscOutPatchpoint[j] = [theTemplate addPatchpoint:MK_xPatch];
  109.   }
  110.     delayIn = [theTemplate addPatchpoint:MK_xPatch];
  111.     delayOut = [theTemplate addPatchpoint:MK_yPatch];
  112.     outPatchpointA = [theTemplate addPatchpoint:MK_xPatch];
  113.     outPatchpointB = [theTemplate addPatchpoint:MK_yPatch];
  114.  
  115.     /* Step 3:  Specify the connections between synthElements. */
  116.     [theTemplate to:ampEnvUG sel:@selector(setOutput:) arg:ampPatchpoint];
  117.   for (j = 0; j < 2; j++) {
  118.     [theTemplate to:freqOscUG[j] sel:@selector(setOutput:) arg:vibMulIn1[j]];
  119.     [theTemplate to:vibDeviateUG[j] sel:@selector(setOutput:)
  120.                             arg:vibMulIn2[j]];
  121.     [theTemplate to:vibMulUG[j] sel:@selector(setInput1:) arg:vibMulIn1[j]];
  122.     [theTemplate to:vibMulUG[j] sel:@selector(setInput2:) arg:vibMulIn2[j]];
  123.     [theTemplate to:vibMulUG[j] sel:@selector(setOutput:) arg:freqEnvIn1[j]];
  124.     [theTemplate to:vibBaseUG[j] sel:@selector(setOutput:) arg:freqEnvIn2[j]];
  125.     [theTemplate to:freqEnvUG[j] sel:@selector(setInput1:) arg:freqEnvIn1[j]];
  126.     [theTemplate to:freqEnvUG[j] sel:@selector(setInput2:) arg:freqEnvIn2[j]];
  127.     [theTemplate to:freqEnvUG[j] sel:@selector(setOutput:)
  128.                             arg:freqPatchpoint[j]];
  129.     [theTemplate to:osc[j] sel:@selector(setAmpInput:) arg:ampPatchpoint];
  130.     [theTemplate to:osc[j] sel:@selector(setIncInput:) arg:freqPatchpoint[j]];
  131.     [theTemplate to:osc[j] sel:@selector(setOutput:) arg:oscOutPatchpoint[j]];
  132.   }
  133.     [theTemplate to:oscSum sel:@selector(setInput1:) arg:oscOutPatchpoint[0]];
  134.     [theTemplate to:oscSum sel:@selector(setInput2:) arg:oscOutPatchpoint[1]];
  135.     [theTemplate to:oscSum sel:@selector(setOutput:) arg:outPatchpointA];
  136.     [theTemplate to:stereoOutA sel:@selector(setInput:) arg:outPatchpointA];
  137.     [theTemplate to:delayUG sel:@selector(setInput:) arg:outPatchpointA];
  138.     [theTemplate to:delayUG sel:@selector(setOutput:) arg:outPatchpointB];
  139.     [theTemplate to:stereoOutB sel:@selector(setInput:) arg:outPatchpointB];
  140.     [theTemplate to:delayUG sel:@selector(setDelayMemory:) arg:DelayLine];
  141.  
  142.     /* Always return the PatchTemplate. */
  143.     return theTemplate;
  144. }
  145.  
  146. - applyParameters:aNote
  147.   /* This is a private method to the Envy class. It is used internally only.
  148.      */
  149. {
  150.     /* Retrieve and store the parameters. */    
  151.     double    myFreq0 = [aNote parAsDouble:MK_freq0];
  152.     double  myFreq1 = [aNote parAsDouble:MK_freq1];
  153.         double    FreqInc;
  154.     double    myAmp = [aNote parAsDouble:MK_amp];
  155. //    double    myBearing = [aNote parAsDouble:MK_bearing];
  156.     double    myVibFreq0 = [aNote parAsDouble:MK_svibFreq];
  157.     double    myVibAmp0 = [aNote parAsDouble:MK_svibAmp];
  158.     double    myVibFreq1 = [aNote parAsDouble:MK_rvibFreq];
  159.     double    myVibAmp1 = [aNote parAsDouble:MK_rvibAmp];
  160.     double    FreqIncHi;
  161.     LoochWave = [aNote parAsWaveTable:MK_waveform];
  162.     
  163.     /* set wavetable if present */
  164.     if (LoochWave != nil) {
  165.         [[self synthElementAt:osc[0]] setTable:LoochWave length:64 
  166.                         defaultToSineROM:YES];
  167.         [[self synthElementAt:osc[1]] setTable:LoochWave length:64
  168.                         defaultToSineROM:YES];
  169.         }
  170.  
  171.     /* Apply frequency if present. */
  172.     if (myFreq0 != MAXDOUBLE) {
  173.         FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0];
  174.         [[self synthElementAt:vibBaseUG[0]] setConstant:FreqInc];
  175.         }
  176.     if (myFreq1 != MAXDOUBLE) {
  177.         FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1];
  178.         [[self synthElementAt:vibBaseUG[1]] setConstant:FreqInc];
  179.         }
  180.     
  181.     /* Apply vibrato freq if present */
  182.     if (myVibFreq0 != MAXDOUBLE) {
  183.         [[self synthElementAt:freqOscUG[0]] setFreq:myVibFreq0];
  184.         }
  185.     if (myVibFreq1 != MAXDOUBLE) {
  186.         [[self synthElementAt:freqOscUG[1]] setFreq:myVibFreq1];
  187.         }
  188.     
  189.     /* Apply vibrato amplitude if present (amp in Hz) */
  190.     if (myVibAmp0 != MAXDOUBLE) {
  191.         FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0];
  192.         FreqIncHi = [[self synthElementAt:osc[0]]
  193.                     incAtFreq:(myFreq0+myVibAmp0)];
  194.         [[self synthElementAt:vibDeviateUG[0]]
  195.                     setConstant:(FreqIncHi-FreqInc)];
  196.         }
  197.     if (myVibAmp1 != MAXDOUBLE) {
  198.         FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1];
  199.         FreqIncHi = [[self synthElementAt:osc[1]]
  200.                     incAtFreq:(myFreq1+myVibAmp1)];
  201.         [[self synthElementAt:vibDeviateUG[1]]
  202.                     setConstant:(FreqIncHi-FreqInc)];
  203.         }
  204.  
  205.     /* Apply amplitude if present. */
  206.     if (myAmp != MAXDOUBLE)
  207.         [[self synthElementAt:ampEnvUG] setTargetVal:myAmp];
  208.  
  209. //    /* Apply bearing if present. */
  210. //    if (myBearing != MAXDOUBLE)
  211. //        [[self synthElementAt:stereoOut] setBearing:myBearing];
  212.       
  213. }
  214.  
  215. - noteOnSelf:aNote
  216. {
  217.    /* Step 1: Read the parameters in the Note and apply them to the patch. */
  218.     [self applyParameters:aNote];
  219.  
  220.     [[self synthElementAt:ampEnvUG] setCurVal:0.0];
  221.     [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampAtt]];
  222.  
  223.     /* Step 2: Turn on the patch by connecting the Out2sumUGx object to the
  224.     patchpoint and sending the run message to all the synthElements. */
  225.     [[self synthElementAt:stereoOutA] 
  226.                  setInput:[self synthElementAt:outPatchpointA]];
  227.     [[self synthElementAt:stereoOutB] 
  228.                  setInput:[self synthElementAt:outPatchpointB]];
  229.     [synthElements makeObjectsPerform:@selector(run)]; 
  230.  
  231.     return self;
  232. }
  233.  
  234. - noteUpdateSelf:aNote
  235. {
  236.     [self applyParameters:aNote];
  237.  
  238.     [[self synthElementAt:ampEnvUG] setTargetVal:0.0];
  239.     [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampRel]];
  240.  
  241.     return self;    
  242. }
  243.  
  244. - (double)noteOffSelf:aNote
  245. {
  246.     [self applyParameters:aNote];
  247.  
  248.     return 0.0;
  249. }
  250.  
  251. - noteEndSelf
  252. {
  253.     /* Deactivate the SynthPatch by idling the output. */
  254.     [[self synthElementAt:stereoOutA] idle];
  255.     [[self synthElementAt:stereoOutB] idle];
  256.  
  257.     return self;
  258. }
  259.  
  260.  
  261. - initialize
  262. {
  263.     /* Initialize is automatically sent once when an instance is created, after
  264.        it's patch has been loaded. */    
  265.     [[self synthElementAt:osc[0]] setTable:nil defaultToSineROM:YES];
  266.     /* full output for vibrato */
  267.     [[self synthElementAt:freqOscUG[0]] setAmp:1.0];
  268.     
  269.     [[self synthElementAt:osc[1]] setTable:nil defaultToSineROM:YES];
  270.     /* full output for vibrato */
  271.     [[self synthElementAt:freqOscUG[1]] setAmp:1.0];
  272.  
  273.     return self;
  274. }  
  275. @end